home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
util
/
cdity
/
ModeProSrc.lha
/
Daemon
/
MPCloseScrPatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-21
|
12KB
|
247 lines
#define DEBUG
#include <debug.h>
#include "MP.h"
//#include "/modepro.h"
#include <graphics/videocontrol.h>
#include <graphics/displayinfo.h>
#include "patchdata.h"
#include <extras/macros/exec.h>
// Window
#ifdef DEBUG
#define ADD_DEBUG_CODE
#endif
extern LONG InPatch;
extern BYTE PublicSignal;
extern struct MPSem *MPSem;
extern struct Process *MPTask;
extern LONG ASM (*OldCloseScreen) (REG __a0 struct Screen *,REG __a6 struct IntuitionBase *);
extern LONG ASM (*OldCloseWorkBench)(REG __a6 struct IntuitionBase *lib);
/* 4.53 moved closing ccde to NewCloseScreen() */
/* called by ModePro */
/* transplanted from mpmain.c */// (4.55.6)
void ClosePubScreens(void) // (4.55.6)
{
struct OpenNode *on,*on2;
// struct List *plist;
// struct PubScreenNode *psn;
ObtainSemaphore(&MPSem->OpenListSem);
/*
// 4.53 @10 Scan pubscreen list and check for screens that need to be closed
plist=LockPubScreenList();
PROCESS_LIST(plist,psn)
{
if(on=FindOpenNode(psn->psn_Screen))
{
if(psn->psn_VisitorCount<=1) // birdie kludge
{
on->Flags|=ON_CLOSEME;
}
}
}
UnlockPubScreenList();
*/
on=(struct OpenNode *)MPSem->OpenList.lh_Head;
// 4.53 rewritten
while(on->on_Node.ln_Succ)
{
on2=(struct OpenNode *)on->on_Node.ln_Succ;
if( (on->Flags & ON_PUBLIC) &&
// (on->Flags & ON_CLOSEME) &&
!(on->Flags & ON_OPEN) &&
(0==on->Screen->FirstWindow))
{
CloseScreen(on->Screen);
}
on=on2;
}
ReleaseSemaphore(&MPSem->OpenListSem);
}
/* Birdie Kludge:
Every time a program UnlockPubScreen()s a screen, MPPatch will signal MP
itself and call ClosePubScreens(), every public screen in the OpenList
with no windows on it will get a CloseScreen() call, if it suceeds then
great, if not then someone else has a lock on it.
*/
LONG __saveds ASM NewCloseScreen(REG __a0 struct Screen *S,// (4.56.5)
REG __a6 struct IntuitionBase *IBase)// (4.56.5)
{
struct OpenNode *on;
BOOL rv;
LONG myrv;
char tnamebuffer[52];
char *tname;
InPatch++;
tname=SetupTaskName(tnamebuffer,", CS",50);
DEBUG_CODE(DKP("CloseScreen(%8lx)\n",S););
ObtainSemaphore(&MPSem->OpenListSem);
// 4.53 @3
if(on=FindOpenNode(S))
{
DEBUG_CODE(DKP(" ModePro has an OpenNode for this screen\n"););
// 4.53 @12
if(on->Flags & ON_PUBLIC) // If this OpenNode belongs to a ModePro public screen then...
{
DEBUG_CODE(DKP(" ModePro made screen public\n"););
if(on->Flags & ON_OPEN)
{ // give control of this screen to MP
on->Flags&=(~ON_OPEN); // This screen is nolonger owned by the program that opened it
S->DefaultTitle=0;
S->Title=0;//on->ScreenTitle; // Reset title since app owns the string.
ShowTitle(S,TRUE); // Refresh Titlebar
on->Flags|=(ON_CLOSEME); // 4.53 @4 - Set flag so MP knows which OpenNode caused signal
Signal((struct Task *)MPTask,1<<PublicSignal); // Signal ModePro so it knows that it should attempt to close this screen
rv=1; // Fake return value, so that apps that DO check this value will think
// that the screen really did close
DEBUG_CODE(DKP(" CloseScreen() fakes close\n"););
}
else // since not ON_OPEN, ModePro itself is trying to close
{
BOOL closeit=0;
BOOL ispublic=0;
struct PubScreenNode *psn;
struct List *plist;
DEBUG_CODE(DKP(" This should only happen on ModePro's task\n"););// (4.55.7)
rv=0; // 4.55 @3 - rv was not initialized to 0 till 4.55
/* The big birdie kludge // (4.55.7)
1. Check to see if the screen is private// (4.55.7)
2. Find out if the screen is private (used later)// (4.55.7)
3. Attempt to make the screen private. This should remove any visitors from the screennotify library. (Birdie)// (4.55.7)
4. Check to see if any visitors are on the screen // (4.55.7)
If none then try to close it// (4.55.7)
5. If it didn't close for some odd reason, then add the backdrop and make the screen public again// (4.55.7)
*/// (4.55.7)
plist=LockPubScreenList(); // (4.55.7)
PROCESS_LIST(plist,psn)// (4.55.7)
{// (4.55.7)
if(S==psn->psn_Screen)// (4.55.7)
{// (4.55.7)
ispublic=!(psn->psn_Flags & PSNF_PRIVATE);// (4.55.7)
}// (4.55.7)
}// (4.55.7)
UnlockPubScreenList();// (4.55.7)
// (4.55.7)
PubScreenStatus(S,PSNF_PRIVATE); // (4.55.7)
// (4.55.7)
plist=LockPubScreenList(); // (4.55.7)
PROCESS_LIST(plist,psn)// (4.55.7)
{// (4.55.7)
if(S==psn->psn_Screen)// (4.55.7)
{// (4.55.7)
if(psn->psn_VisitorCount==0)// (4.55.7)
{// (4.55.7)
closeit=1;// (4.55.7)
}// (4.55.7)
}// (4.55.7)
}// (4.55.7)
UnlockPubScreenList();// (4.55.7)
// (4.55.7)
if(closeit)// Only close it if no visitors (4.55.7)
{// (4.55.7)
RemoveBackdrop(S); // Remove any backdrop (handles no backdrops) (4.55.7)
PreCloseOpenNode(on); // Free data that needs to be freed BEFORE the screen closes (ie Pens) (4.55.7)
// (4.55.7)
if(rv=OldCloseScreen(S,IntuitionBase)) // Attempt to Close the screen // (4.55.7)
{// (4.55.7)
Remove((struct Node *)on); // 4.53 @12 - Remove Node from OpenList// (4.55.7)
FreeOpenNode(on); // Free the OpenNode// (4.55.7)
DEBUG_CODE(DKP(" CloseScreen() really closes screen!\n"););// (4.55.7)
}// (4.55.7)
}// (4.55.7)
// (4.55.7)
if(ispublic && !rv) // if the screen was public and closescreen failed.// (4.55.7)
{// (4.55.7)
PubScreenStatus(S,0); // Then make the screen public again.// (4.55.7)
AddBackdrop(S,on->DN); // Re add the backdrop// (4.55.7)
}// (4.55.7)
}// (4.55.7)
}
else // If this OpenNode belongs to a non-public promoted screen.
{
DEBUG_CODE(DKP(" ModePro did NOT make screen public\n"););
SendMPMsg(MP_SCREENCLOSING,0,on); // Let ModePro know that we're closing this screen.
PreCloseOpenNode(on); // Free data that needs to be freed BEFORE the screen closes (ie Pens)
if(rv=OldCloseScreen(S,IBase)) // Attempt to Close the screen
{
Remove((struct Node *)on); // 4.53 @12 - Remove Node from OpenList
FreeOpenNode(on); // Free the OpenNode
}
}
}
else // on==NULL
{ // Non-promoted screen
DEBUG_CODE(DKP(" ModePro doesn't have an OpenNode for this screen\n"););
rv=OldCloseScreen(S,IBase);
}
myrv=(rv?1:0);
DEBUG_CODE( DKP(" RV=%lx (1 second delay)\n",myrv);
Delay(50); );
InPatch--;
ReleaseSemaphore(&MPSem->OpenListSem);
SetTaskName(tname);
return(myrv);
}
LONG __saveds ASM NewCloseWorkBench(REG __a6 struct IntuitionBase *IBase)
{
LONG retval;
char tnamebuffer[52];
char *tname;
tname=SetupTaskName(tnamebuffer,", CWB",50);
DEBUG_CODE(DKP("CloseWorkBench()\n"););
//ObtainSemaphore(&MPSem->OpenListSem);
//SendMPMsg(MP_SCREENCLOSING,0,0,ON);
PreCloseWBOpenNode();
if(retval=OldCloseWorkBench(IBase))
FreeWBOpenNode();
//ReleaseSemaphore(&MPSem->OpenListSem);
DEBUG_CODE(DKP(" RV=%d\n",retval););
SetTaskName(tname);
return(retval);
}